home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 6
/
Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso
/
038a
/
bas_int1.zip
/
COPY.BAS
< prev
next >
Wrap
BASIC Source File
|
1991-06-12
|
5KB
|
120 lines
'=========================================================================
'Routine Type: FUNCTION
' Name: COPY.BAS by Dave Cleary
' Purpose: To copy a file without using SHELL "COPY..."
' Call Syntax: CopyFile% (Source$, Dest$)
' Returns: 0 - Everything went all right
' 1 - Source file does not exist
' 2 - Destination file does exist
' 3 - Failure in setting copy's time/date to that of source
' Libraries: QB.QLB (QB.LIB) for CALL INTERRUPT
'External Routines Required: DIR$ function with QuickBASIC v4.x
' also written by Dave Cleary
'
'-----------------------------------------------------------------------
'Background Information:
'
' QuickBASIC has many different ways to read an write files. Copying
'files is easily done in QuickBASIC and is quite fast also.
'
' Lets first look at the options QB gives us to read a file. The three
'major commands to read a file are LINE INPUT, INPUT$, and GET. LINE
'INPUT is only good for text files and is also one of the slowest QB
'commands as far as file IO goes. That leaves INPUT$ and GET.
'
' GET and PUT are by far the fastest IO commands QB has. This is
'because with GET, the area of memory where the data gets placed is
'already allocated. All QB has to do is set up some registers and then
'call DOS to read the file.
'
' INPUT$ is another command that works for both text and binary files.
'INPUT$ is slightly slower than the GET command because it allocates
'memory to hold the data each time it is called. I have found this speed
'difference to be inconsequential though. INPUT$ does offer some
'advantages over GET in our CopyFile routine. When you are at the end of
'a file, INPUT$ will return a string with the exact number of bytes left
'in the file even if you asked for more. This relieves us of knowing the
'size of the file we are working with. GET, on the other hand, will pad
'your buffer with null characters, causing us to have to truncate the
'last read if we want to keep our file lengths the same. For this reason,
'I chose INPUT$ over GET to read in the file.
'
'========================================================================
'
'So here is our copy file routine:
'Main()
DEFINT A-Z
DECLARE FUNCTION DIR$ (FileSpec$) 'Comment out if using BASIC 7
DECLARE FUNCTION CopyFile% (Source$, Dest$)
'$INCLUDE: 'QB.BI' 'Required for CALL INTERRUPT
CONST Block = 4096 'Set this to the length you
'want your buffer to be
'Example of how to call CopyFile
'Ercd = CopyFile("D:\PDQ\HISTORY.DOC", "C:\SCRAP\TEST1")
FUNCTION CopyFile% (Source$, Dest$) STATIC
DIM Regs AS RegType 'Needed for CALL INTERRUPT
'----- See if source file exists
IF LEN(DIR$(Source$)) = 0 THEN 'Use my DIR$ function
'if you are
'using QB 4.x.
CopyFile% = 1 'Source doesn't exist
EXIT FUNCTION 'Exit with error code
END IF
'----- See if destination exists
IF LEN(DIR$(Dest$)) THEN
CopyFile% = 2 'Destination already exists
EXIT FUNCTION 'Exit with error code
END IF
'----- Open files for BINARY
SFileNum = FREEFILE
OPEN Source$ FOR BINARY AS #SFileNum
DFileNum = FREEFILE
OPEN Dest$ FOR BINARY AS #DFileNum
'----- Now copy the files over
DO
Buffer$ = INPUT$(Block, #SFileNum)
PUT #DFileNum, , Buffer$
LOOP UNTIL EOF(SFileNum)
'----- Set the date and time of the copy to that of the original
Regs.ax = &H5700
Regs.bx = FILEATTR(SFileNum, 2) 'This gets DOS's file handle
INTERRUPT &H21, Regs, Regs 'Get date and time of original
'----- Check for an error
IF (Regs.flags AND 1) THEN
CLOSE #SFileNum, #DFileNum 'Close the files
KILL Dest$ 'Kill our copy because something
CopyFile% = 3 'went wrong. Exit with error
EXIT FUNCTION
END IF
Regs.ax = &H5701
Regs.bx = FILEATTR(DFileNum, 2)
INTERRUPT &H21, Regs, Regs 'Set date and time of copy
'----- Check for an error
IF (Regs.flags AND 1) THEN
CLOSE #SFileNum, #DFileNum 'Close the files
KILL Dest$ 'Kill our copy because something
CopyFile% = 3 'went wrong. Exit with error
EXIT FUNCTION
END IF
CLOSE #SFileNum, #DFileNum 'All done
CopyFile% = 0 'Return with success
END FUNCTION